package com.isyscore.os.metadata.service.impl;

import com.isyscore.os.core.exception.DataFactoryException;
import com.isyscore.os.core.exception.ErrorCode;
import com.isyscore.os.metadata.constant.TaskConstant;
import com.isyscore.os.metadata.model.dto.TaskDTO;
import com.isyscore.os.metadata.service.TaskService;
import com.isyscore.os.metadata.utils.UdmpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author fjZheng
 * @version 1.0
 * @date 2020/11/24 20:00
 */
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    @Resource(name = "redisTemplate")
    private ValueOperations<String, TaskDTO> taskValue;

    @Override
    public String creatTask(Long time, TimeUnit t, String data) {
        if (time == null) {
            time = 1L;
        }
        if (t == null) {
            t = TimeUnit.HOURS;
        }
        TaskDTO taskDTO = new TaskDTO();
        taskDTO.setProgress(0.0);
        taskDTO.setIsStop(TaskConstant.NOT_STOP);
        taskDTO.setData(data);
        String taskId = TaskConstant.TASK_NAME + UdmpUtils.Guid();
        taskValue.set(TaskConstant.UDMP_REDIS_KEY+taskId, taskDTO, time, t);
        return taskId;
    }

    @Override
    public Double getProgress(String taskId) {
        TaskDTO taskDTO = taskValue.get(TaskConstant.UDMP_REDIS_KEY+taskId);
        if (taskDTO == null ) {
            throw new DataFactoryException(ErrorCode.TASK_IS_NULL);
        }
        if (Objects.equals(taskDTO.getIsStop(), TaskConstant.STOP)) {
            throw new DataFactoryException(ErrorCode.TASK_IS_STOP, taskDTO.getErrorMsg());
        }
        return taskDTO.getProgress();
    }

    @Override
    public boolean stopTask(String taskId, String errorMsg) {
        TaskDTO taskDTO = taskValue.get(TaskConstant.UDMP_REDIS_KEY+taskId);
        if (taskDTO == null || taskDTO.getProgress() > 99.99) {
            return false;
        }

        taskDTO.setIsStop(TaskConstant.STOP);
        taskDTO.setErrorMsg(errorMsg);
        taskValue.set(TaskConstant.UDMP_REDIS_KEY+taskId, taskDTO, 1, TimeUnit.HOURS);
        return true;
    }

    @Override
    public boolean isTaskStop(String taskId) {
        TaskDTO taskDTO = taskValue.get(TaskConstant.UDMP_REDIS_KEY+taskId);
        if (taskDTO == null) {
            throw new DataFactoryException(ErrorCode.TASK_IS_NULL);
        }
        if (Objects.equals(taskDTO.getIsStop(), TaskConstant.STOP)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void setTaskProgress(String taskId, Double progress) {
        if (taskId != null && progress != null) {
            TaskDTO taskDTO = taskValue.get(TaskConstant.UDMP_REDIS_KEY+taskId);
            if (taskDTO == null || Objects.equals(taskDTO.getIsStop(), TaskConstant.STOP) ) {
                throw new DataFactoryException(ErrorCode.TASK_IS_NULL);
            }
            taskDTO.setProgress(progress);
            taskValue.set(TaskConstant.UDMP_REDIS_KEY+taskId, taskDTO, 1, TimeUnit.HOURS);
        }
    }

    @Override
    public TaskDTO get(String taskId) {
        TaskDTO taskDTO = taskValue.get(TaskConstant.UDMP_REDIS_KEY+taskId);
        if (taskDTO == null) {
            throw new DataFactoryException(ErrorCode.TASK_IS_NULL);
        }
        return taskDTO;
    }

    @Override
    public void update(TaskDTO taskDTO) {
        if (taskDTO == null) {
            throw new DataFactoryException(ErrorCode.TASK_IS_NULL);
        }
        taskValue.set(TaskConstant.UDMP_REDIS_KEY+taskDTO.getTaskId(), taskDTO, 1, TimeUnit.HOURS);
    }
}
